using KnowledgeQA.Models.Entities;

namespace KnowledgeQA.Core.Interfaces
{
    /// <summary>
    /// 向量服务接口
    /// </summary>
    public interface IVectorService
    {
        /// <summary>
        /// 向量数据库类型
        /// </summary>
        string VectorDbType { get; }

        /// <summary>
        /// 添加向量
        /// </summary>
        /// <param name="vectorId">向量ID</param>
        /// <param name="vector">向量数据</param>
        /// <param name="metadata">元数据</param>
        /// <returns>是否成功</returns>
        Task<bool> AddVectorAsync(string vectorId, float[] vector, Dictionary<string, object>? metadata = null);

        /// <summary>
        /// 批量添加向量
        /// </summary>
        /// <param name="vectors">向量数据列表</param>
        /// <returns>是否成功</returns>
        Task<bool> AddVectorsAsync(IEnumerable<VectorData> vectors);

        /// <summary>
        /// 删除向量
        /// </summary>
        /// <param name="vectorId">向量ID</param>
        /// <returns>是否成功</returns>
        Task<bool> DeleteVectorAsync(string vectorId);

        /// <summary>
        /// 批量删除向量
        /// </summary>
        /// <param name="vectorIds">向量ID列表</param>
        /// <returns>是否成功</returns>
        Task<bool> DeleteVectorsAsync(IEnumerable<string> vectorIds);

        /// <summary>
        /// 相似度搜索
        /// </summary>
        /// <param name="queryVector">查询向量</param>
        /// <param name="topK">返回结果数量</param>
        /// <param name="minScore">最小相似度分数</param>
        /// <param name="filter">过滤条件</param>
        /// <returns>搜索结果</returns>
        Task<List<VectorSearchResult>> SearchAsync(float[] queryVector, int topK = 5, double minScore = 0.7, Dictionary<string, object>? filter = null);

        /// <summary>
        /// 更新向量
        /// </summary>
        /// <param name="vectorId">向量ID</param>
        /// <param name="vector">新的向量数据</param>
        /// <param name="metadata">新的元数据</param>
        /// <returns>是否成功</returns>
        Task<bool> UpdateVectorAsync(string vectorId, float[] vector, Dictionary<string, object>? metadata = null);

        /// <summary>
        /// 获取向量
        /// </summary>
        /// <param name="vectorId">向量ID</param>
        /// <returns>向量数据</returns>
        Task<VectorData?> GetVectorAsync(string vectorId);

        /// <summary>
        /// 检查服务是否可用
        /// </summary>
        /// <returns>是否可用</returns>
        Task<bool> IsAvailableAsync();

        /// <summary>
        /// 获取统计信息
        /// </summary>
        /// <returns>统计信息</returns>
        Task<VectorDbStats> GetStatsAsync();
    }

    /// <summary>
    /// 向量数据
    /// </summary>
    public class VectorData
    {
        /// <summary>
        /// 向量ID
        /// </summary>
        public string VectorId { get; set; } = string.Empty;

        /// <summary>
        /// 向量数据
        /// </summary>
        public float[] Vector { get; set; } = Array.Empty<float>();

        /// <summary>
        /// 元数据
        /// </summary>
        public Dictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
    }

    /// <summary>
    /// 向量搜索结果
    /// </summary>
    public class VectorSearchResult
    {
        /// <summary>
        /// 向量ID
        /// </summary>
        public string VectorId { get; set; } = string.Empty;

        /// <summary>
        /// 相似度分数
        /// </summary>
        public double Score { get; set; }

        /// <summary>
        /// 元数据
        /// </summary>
        public Dictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
    }

    /// <summary>
    /// 向量数据库统计信息
    /// </summary>
    public class VectorDbStats
    {
        /// <summary>
        /// 向量总数
        /// </summary>
        public long TotalVectors { get; set; }

        /// <summary>
        /// 向量维度
        /// </summary>
        public int VectorDimension { get; set; }

        /// <summary>
        /// 索引大小（字节）
        /// </summary>
        public long IndexSize { get; set; }

        /// <summary>
        /// 最后更新时间
        /// </summary>
        public DateTime LastUpdated { get; set; }
    }
} 